
// class B:
// using System.IO;
using System.Buffers.Text;
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Threading.Tasks;
using UMC.SshNet;
using UMC.Net;
using System.Text;

namespace UMC.ITME;
class HttpLoger : NetLoger
{
    public HttpLoger(ByteChunk byteChunk) : base(byteChunk)
    {
        this._byteChunk.Temp((byte)0);
        this._byteChunk.Temp((byte)8);
        this._byteChunk.Temp(Utility.TimeSpan());
        this._byteChunk.Temp(0);
        this._byteChunk.Temp();

    }

    public NetLoger Write(HttpLogerType ctype, int stringValue)
    {
        var type = (byte)ctype;
        if (type <= 0xf)
        {

            this.End();
            this.SetSizeType(type);

            this._byteChunk.Temp((byte)(type << 4));
            this._byteChunk.Temp((byte)4);
            this._byteChunk.Temp(stringValue);
            this._byteChunk.Temp();
            _startIndex = this._byteChunk.Size;
            this._type = 0;

        }
        return this;
    }
    public NetLoger Write(HttpLogerType ctype, params StringValue[] stringValue)
    {
        var type = (byte)ctype;
        if (type <= 0xf)
        {
            this.End();
            
            var ts = stringValue.Sum(x => x?.Length ?? 0);
            if (ts > MaxLogLength)
            {
                ts = MaxLogLength;
            }

            ushort t = (ushort)ts;

            byte v = (byte)(type << 4);


            SetSizeType(type);
            _startIndex = this._byteChunk.Size;

            this._byteChunk.Temp(t);
            this._byteChunk.Chunk.AsSpan(_startIndex, 2).Reverse();


            this._byteChunk.Chunk[_startIndex] += v;
            foreach (var s in stringValue)
            {
                if (s != null)
                {
                    if (s.Length <= ts)
                    {
                        this._byteChunk.Temp(s.Span);
                        ts -= s.Length;
                    }
                    else
                    {
                        this._byteChunk.Temp(s.Span.Slice(0, ts));
                        break;

                    }
                }

            }
            this._byteChunk.Temp();
            this._type = 0;

        }
        return this;
    }
    public NetLoger Write(HttpLogerType ctype, string stringValue)
    {
        var type = (byte)ctype;
        if (type <= 0xf)
        {
            this.End();
            this._startIndex = this._byteChunk.Size;
            this._byteChunk.Temp(type);
            this._byteChunk.Temp(type);
            this._byteChunk.Temp(stringValue);

            var ts = this._byteChunk.TempSize - 2;
            if (ts > MaxLogLength)
            {
                this._byteChunk.Scale(ts - MaxLogLength);
                ts = MaxLogLength;
            }
            ushort t = (ushort)ts;
            var lenValue = this._byteChunk.Chunk.AsSpan(this._startIndex, 2);

            BitConverter.TryWriteBytes(lenValue, t);
            lenValue.Reverse();
            SetSizeType(type);
            byte v = (byte)(type << 4);
            this._byteChunk.Chunk[_startIndex] += v;
            this._byteChunk.Temp();


            this._type = 0;
        }
        return this;
    }
    public NetLoger Write(HttpLogerType ctype, ReadOnlySpan<byte> stringValue)
    {
        var type = (byte)ctype;
        if (type <= 0xf)
        {
            this.End();

            var ts = stringValue.Length;
            if (ts > MaxLogLength)
            {
                ts = MaxLogLength;
            }

            ushort t = (ushort)ts;

            byte v = (byte)(type << 4);


            SetSizeType(type);
            _startIndex = this._byteChunk.Size;

            this._byteChunk.Temp(t);

            this._byteChunk.Chunk.AsSpan(_startIndex, 2).Reverse();

            this._byteChunk.Chunk[_startIndex] += v;
            this._byteChunk.Temp(stringValue.Slice(0, ts));
            this._byteChunk.Temp();
            this._startIndex = this._byteChunk.Size;

            this._type = 0;


        }
        return this;
    }
    public NetLoger Body()
    {
        return Log(14);
    }

}

public enum HttpLogerType : byte
{
    Time = 0,
    Info = 1,
    Alert = 2,
    Debug = 3,
    Error = 4,
    Host = 5,
    UserAgent = 6,
    IP = 7,
    Referer = 8,
    Path = 9,
    Fingerprint = 10,
    Status = 11,
    Duration = 12,
    Username = 13,
    Body = 14
}